<?php

namespace tmcore\services\crud\generators;

use tmcore\services\crud\enum\FormTypeEnum;
use tmcore\services\crud\enum\SearchEnum;
use tmcore\services\crud\enum\TplEnum;
use tmcore\services\crud\UtilService;
use tmcore\services\ImportExcelService;

class Service extends Generate
{
    /**
     * @var string
     */
    protected string $fileType = 'php';

    /**
     * 替换变量
     */
    public function replaceContent()
    {
        $search = [
            '{NAMESPACE}',
            '{USE}',
            '{TABLE_COMMENT}',
            '{CAMEL_CLASS_NAME}',
            '{CONTENT_PHP}',
        ];

        $replace = [
            $this->getNameSpaceContent(),
            $this->getUseContent(),
            $this->getTableCommentContent(),
            $this->getCamelClassName(),
            $this->getServiceContent()
        ];

        $content = UtilService::replaceFileContent($search, $replace, $this->getStub('service'));

        $this->setContent($content);
    }

    /**
     * 返回模板路径
     * @param string $type
     * @return mixed|string|string[]
     */
    public function getStub(string $type = 'service')
    {
        $basePath = 'php/service/';

        $stubs = [
            'lists' => $this->getTplPath($basePath . 'lists'),
            'treeLists' => $this->getTplPath($basePath . 'treeLists'),
            'detail' => $this->getTplPath($basePath . 'detail'),
            'add' => $this->getTplPath($basePath . 'add'),
            'edit' => $this->getTplPath($basePath . 'edit'),
            'delete' => $this->getTplPath($basePath . 'delete'),
            'export' => $this->getTplPath($basePath . 'export'),
            'import' => $this->getTplPath($basePath . 'import'),
            'treeAll' => $this->getTplPath($basePath . 'treeAll'),
            'service' => $this->getTplPath($basePath . 'service'),
        ];

        return $type ? $stubs[$type] : $stubs;
    }

    /**
     * 设置文件路径
     */
    public function setFilePath()
    {
        $name = $this->getCamelClassName() . 'Service.' . $this->fileType;
        $this->setCrudFileName($name);

        $module_path = $this->basePath . $this->moduleName . '/service/';
        if (!empty($this->classDir)) $module_path .= $this->classDir . '/';
        $this->setCrudModuleFilePath($module_path);

        $data_path = $this->crudDir . 'php/app/' . $this->moduleName . '/service/';
        if (!empty($this->classDir)) $data_path .= $this->classDir . '/';
        $this->setCrudDataFilePath($data_path);
    }

    /**
     * 获取服务类内容
     * @return string|string[]
     */
    public function getServiceContent()
    {

        $search = [
            '{TABLE_COMMENT}',
            '{UPPER_TABLE_NAME}',
            '{CAMEL_CLASS_NAME}',
            '{PK}',
            '{SEARCH}',
            '{FIELD}',
            '{KEY}',
            '{APPEND}',
            '{DETAIL_APPEND}',
            '{WITH}',
            '{ADD_DATA}',
            '{EDIT_DATA}',
            '{EXPORT_ITEM}',
            '{EXPORT_HEADER}',
            '{IMPORT_KEY_PARAM}',
            '{IMPORT_ADD_PARAM}',
            '{TREE_ID}',
            '{TREE_PID}',
            '{TREE_NAME}',
            '{AUTHOR}'
        ];

        $replace = [
            $this->crudData['table_comment'],
            $this->getCamelTableName(),
            $this->getCamelClassName(),
            $this->getPk(),
            $this->getSearchContent(),
            $this->getFieldContent(),
            $this->getPk(),
            $this->getAppendContent(),
            $this->getAppendContent(true),
            $this->getWithContent(),
            $this->getAddDataContent(),
            $this->getEditDataContent(),
            $this->getExportItemContent(),
            $this->getExportHeaderContent(),
            $this->getImportKeyParamContent(),
            $this->getImportAddParamContent(),
            $this->treeConfig['tree_id'] ?? 'id',
            $this->treeConfig['tree_pid'] ?? 'pid',
            $this->treeConfig['tree_name'] ?? 'name',
            $this->getAuthorContent()
        ];

        return substr(UtilService::replaceFileContent($search, $replace, $this->getStubContent(TplEnum::getServiceTpl($this->crudData, $this->isTypeTree())), false), 0, -1);
    }

    /**
     * 获取查询内容
     * @return string
     */
    public function getSearchContent()
    {
        if (empty($this->crudColumn)) return '';

        $search_type_arr = SearchEnum::SEARCH_TYPE;
        $data_arr = [];

        foreach ($this->crudColumn as $key => $value) {
            if ($value['is_query'] && in_array($value['query_type'], $search_type_arr)) {
                $search_key = SearchEnum::getUseType($value['query_type'], $value['view_type'], $value['extra']);
                if (!isset($data_arr[$search_key])) $data_arr[$search_key] = '';
                if ($value['query_type'] == SearchEnum::SEARCH_BETWEEN && $value['view_type'] != FormTypeEnum::DATE_PICKER) {
                    $search_column = $value['column_name'] . '_start|' . $value['column_name'] . '_end';
                } elseif ($value['query_type'] == SearchEnum::SEARCH_IN) {
                    $search_column = $value['column_name'] . '@' . $value['column_name'];
                } else {
                    $search_column = $value['column_name'];
                }
                if ($data_arr[$search_key]) {
                    $data_arr[$search_key] .= ', ' . "'{$search_column}'";
                } else {
                    $data_arr[$search_key] = "'{$search_column}'";
                }
            }
        }

        $tab3 = UtilService::tab(3);

        $arr_str = '';
        $num = 0;
        foreach ($data_arr as $key => $value) {
            $comma = (count($data_arr) - $num) > 1?',':'';
            $arr_str .= <<<CONTENT
{$tab3}'$key' => [$value]$comma
CONTENT. PHP_EOL;
            $num++;
        }

        if ($arr_str) $arr_str = substr($arr_str, 0, -1);

        return $arr_str;
    }

    /**
     * 获取查询field
     * @return string
     */
    public function getFieldContent()
    {
        if (empty($this->crudColumn)) return '*';

        $content = '';

        $tree_column = [];
        if($this->isTypeTree()) {
            array_push($tree_column, $this->treeConfig['tree_id'] ?? 'id', $this->treeConfig['tree_pid'] ?? 'pid', $this->treeConfig['tree_name'] ?? 'name');
        }

        foreach ($this->crudColumn as $key => $value) {
            if ($value['is_list'] || $value['is_pk'] || in_array($value['column_name'],$tree_column)) {
                if ($content) {
                    $content .= ', ' . "'{$value['column_name']}'";
                } else {
                    $content = "'{$value['column_name']}'";
                }
            }
        }

        return <<<CONTENT
[$content]
CONTENT;
    }

    /**
     * 获取查询append
     * @param $is_all
     * @return string
     */
    public function getAppendContent($is_all = false)
    {
        if (empty($this->crudColumn)) return '';

        $prefix = UtilService::lower($this->attrPrefix);
        $content = '';

        foreach ($this->crudColumn as $key => $value) {
            if (isset($this->params['crud_column_check']['append_fields']) && in_array($value['column_name'], $this->params['crud_column_check']['append_fields'])) {
                if(!$is_all && !$value['is_list']) continue;
                if ($content) {
                    $content .= ', ' . "'{$value['column_name']}_{$prefix}'";
                } else {
                    $content = "'{$value['column_name']}_{$prefix}'";
                }
            }
        }

        return <<<CONTENT
[$content]
CONTENT;
    }

    /**
     * 获取查询with
     * @return string
     */
    public function getWithContent()
    {
        if (empty($this->crudColumn)) return '';

        $content = '';

        if($this->joinConfig) {
            $join_content = '';
            foreach ($this->joinConfig as $key => $value) {
                $prefix = UtilService::snake($value['type']);
                if ($join_content) {
                    $join_content .= ', ' . "'{$value['name']}_{$prefix}'";
                } else {
                    $join_content = "'{$value['name']}_{$prefix}'";
                }
            }

            $content .= <<<CONTENT
with([$join_content])->
CONTENT;
        }

        return $content;
    }

    /**
     * 添加内容
     * @return string
     */
    public function getAddDataContent()
    {
        $list = [];
        foreach ($this->crudColumn as $key => $value) {
            if ($value['is_insert'] && (!$value['is_pk'])) {
                if ($value['view_type'] == 'datePicker') {
                    $add_value = '$params[' . "'" . $value['column_name'] . "'" . '] ? strtotime($params[' . "'" . $value['column_name'] . "'" . ']):0';
                } else {
                    $add_value = '$params[' . "'" . $value['column_name'] . "'" . ']';
                }
                array_push($list, ['name' => $value['column_name'], 'value' => $add_value]);
            }
        }
        $tab3 = UtilService::tab(3);

        $arr_str = '';
        $len = count($list);
        foreach ($list as $key => $value) {
            $comma = (count($list) - $key) > 1?',':'';
            $arr_str .= <<<CONTENT
{$tab3}'$value[name]' => $value[value]$comma
CONTENT. ($key < ($len - 1) ? PHP_EOL : '');
        }

        return $arr_str;
    }

    /**
     * 编辑内容
     * @return string
     */
    public function getEditDataContent()
    {
        $list = [];
        foreach ($this->crudColumn as $key => $value) {
            if ($value['is_update'] && (!$value['is_pk'])) {
                if ($value['view_type'] == 'datePicker') {
                    $add_value = '$params[' . "'" . $value['column_name'] . "'" . '] ? strtotime($params[' . "'" . $value['column_name'] . "'" . ']):0';
                } else {
                    $add_value = '$params[' . "'" . $value['column_name'] . "'" . ']';
                }
                array_push($list, ['name' => $value['column_name'], 'value' => $add_value]);
            }
        }
        $tab3 = UtilService::tab(3);

        $arr_str = '';
        $len = count($list);
        foreach ($list as $key => $value) {
            $comma = (count($list) - $key) > 1?',':'';
            $arr_str .= <<<CONTENT
{$tab3}'$value[name]' => $value[value]$comma
CONTENT. ($key < ($len - 1) ? PHP_EOL : '');
        }

        return $arr_str;
    }

    /**
     * 导出字段信息内容
     * @return string
     */
    public function getExportItemContent()
    {
        $list = [];
        $form_type_arr = ['select', 'radio', 'checkbox', 'datePicker', 'timePicker', 'areaSelect'];
        $prefix = UtilService::lower($this->attrPrefix);

        foreach ($this->crudColumn as $key => $value) {
            if ($value['is_list'] && (!in_array($value['column_name'], UtilService::getIgnoreFields())) && in_array($value['view_type'], $form_type_arr) && (!$value['is_pk'])) {
                switch ($value['view_type']) {
                    case 'select':
                        if (!empty($value['extra']['multiple'])) {
                            $view_value = 'explode(' . "'、'" . ', $item[' . "'" . $value['column_name'] . '_' . $prefix . "'" . ']);';
                        } else {
                            $view_value = '$item[' . "'" . $value['column_name'] . '_' . $prefix . "'" . '];';
                        }
                        break;
                    case 'radio':
                        $view_value = '$item[' . "'" . $value['column_name'] . '_' . $prefix . "'" . '];';
                        break;
                    case 'checkbox':
                        $view_value = 'explode(' . "'、'" . ', $item[' . "'" . $value['column_name'] . '_' . $prefix . "'" . ']);';
                        break;
                    case 'datePicker':
                        $view_value = '$item[\'' . $value['column_name'] . '\'] ? date(\'Y-m-d H:i:s\', $item[\'' . $value['column_name'] . '\']):\'\';';
                        break;
                    case 'timePicker':
                        $view_value = '$item[\'' . $value['column_name'] . '\'] ? date(\'H:i:s\', $item[\'' . $value['column_name'] . '\']):\'\';';
                        break;
                    case 'areaSelect':
                        $view_value = '$item[\'' . $value['column_name'] . '_' . $prefix . '\'] ? ($item[\'' . $value['column_name'] . '_' . $prefix . '\'][0][\'name\'] . \'/\' . $item[\'' . $value['column_name'] . '_' . $prefix . '\'][1][\'name\'] . \'/\' . $item[\'' . $value['column_name'] . '_' . $prefix . '\'][2][\'name\']) :\'\';';
                        break;
                    default:
                        $view_value = '$item[' . "'" . $value['column_name'] . "'" . '];';
                        break;
                }
                array_push($list, ['name' => $value['column_name'], 'value' => $view_value]);
            }
        }
        $tab3 = UtilService::tab(3);

        $arr_str = '';
        $len = count($list);
        foreach ($list as $key => $value) {
            $arr_str .= <<<CONTENT
{$tab3}\$item['$value[name]'] = $value[value]
CONTENT. ($key < ($len - 1) ? PHP_EOL : '');
        }

        return $arr_str;
    }

    /**
     * 导出标题字段内容
     * @return string
     */
    public function getExportHeaderContent()
    {
        $list = [];
        foreach ($this->crudColumn as $key => $value) {
            if ($value['is_list']) {
                array_push($list, ['name' => $value['column_name'], 'value' => $this->getTableColumnComment($value['column_comment'])]);
            }
        }
        $tab3 = UtilService::tab(3);

        $arr_str = '';
        $len = count($list);
        foreach ($list as $key => $value) {
            $arr_str .= <<<CONTENT
{$tab3}'$value[name]' => '$value[value]',
CONTENT. ($key < ($len - 1) ? PHP_EOL : '');
        }

        return $arr_str;
    }

    /**
     * 导入表字段映射
     * @return string
     */
    public function getImportKeyParamContent()
    {
        $list = [];

        foreach ($this->crudColumn as $key => $value) {
            if (($value['is_update'] || $value['is_insert']) && (!$value['is_pk'])) {
                array_push($list, ['name' => $value['column_name']]);
            }
        }
        $tab3 = UtilService::tab(3);

        $arr_str = '';
        $len = count($list);
        foreach ($list as $key => $value) {
            $comma = (count($list) - $key) > 1?',':'';
            $arr_str .= <<<CONTENT
{$tab3}'$value[name]' => $key$comma
CONTENT. ($key < ($len - 1) ? PHP_EOL : '');
        }

        return $arr_str;
    }

    /**
     * 生成excel示例文件
     * @return string
     */
    public function createExcelTemplate()
    {
        $header = [];
        foreach ($this->crudColumn as $key => $value) {
            if (($value['is_update'] || $value['is_insert']) && (!$value['is_pk'])) {
                array_push($header, $this->getTableColumnComment($value['column_comment']));
            }
        }

        ImportExcelService::createExcelTemplate($header, $this->crudData['table_comment'] .'导入示例');
    }


    /**
     * 添加表字段映射
     * @return string
     */
    public function getImportAddParamContent()
    {
        $list = [];
        $intFieldValue = ['tinyint', 'smallint', 'mediumint', 'int', 'integer', 'bigint'];

        foreach ($this->crudColumn as $key => $value) {
            if (($value['is_update'] || $value['is_insert']) && (!$value['is_pk'])) {
                array_push($list, ['name' => $value['column_name'], 'value' => in_array($value['column_type'], $intFieldValue) ? 0 : "''"]);
            }
        }
        $tab4 = UtilService::tab(4);

        $arr_str = '';
        $len = count($list);
        foreach ($list as $key => $value) {
            $comma = (count($list) - $key) > 1?',':'';
            $arr_str .= <<<CONTENT
{$tab4}'$value[name]' => \$value[$key] ?? {$value['value']}$comma
CONTENT. ($key < ($len - 1) ? PHP_EOL : '');
        }

        return $arr_str;
    }

    /**
     * 获取命名空间内容
     * @return string
     */
    public function getNameSpaceContent()
    {
        if (!empty($this->classDir)) return "namespace app\\" . $this->moduleName . "\\service\\" . $this->classDir . ';';
        return "namespace app\\" . $this->moduleName . "\\service;";
    }

    /**
     * 获取use内容
     * @return string
     */
    public function getUseContent()
    {
        $tpl = "use app\\common\\model\\" . $this->getCamelTableName() . ';' . PHP_EOL;
        if (!empty($this->classDir)) $tpl = "use app\\common\\model\\" . $this->classDir . "\\" . $this->getCamelTableName() . ';' . PHP_EOL;
        if (!empty($this->crudData['is_export'])) $tpl .= "use app\\admin\\service\\ExportService;" . PHP_EOL;
        if (!empty($this->crudData['is_import'])) $tpl .= "use tmcore\\services\\ImportExcelService;" . PHP_EOL;

        $tpl = substr($tpl, 0, -1);

        return $tpl;
    }

    /**
     * 获取类描述
     * @return string
     */
    public function getTableCommentContent()
    {
        if (!empty($this->crudData['table_comment'])) {
            $tpl = $this->crudData['table_comment'] . '服务类';
        } else {
            $tpl = $this->getCamelClassName() . '服务类';
        }
        return $tpl;
    }
}